<script setup lang="ts">
import { DataNode } from 'ant-design-vue/es/tree';
import {
  deptAllTreeApi, DeptAllTreeRes, getDeptUserAllApi,
  GetDeptUserAllRes, addDeptApi, updateDeptApi, deleteDeptApi
} from '@/api/dept'
import { SysDept, SysUser, CrudBack, R } from '@/interface/user';
import { BankOutlined, ApartmentOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons-vue';
import { ColumnsType } from 'ant-design-vue/es/table';
import { h } from 'vue'
import { message } from 'ant-design-vue';
import { Key } from 'ant-design-vue/es/_util/type';
import { useGlobalStore } from '@/store/globalStore';

const deptTreeData = ref<DataNode[]>([])
const deptList = ref<SysDept[]>([])
const antIcons: any = inject('antIcons')
const isLoading = ref<boolean>(false)
const tabKey = ref<string>('1')

//部门用户列
const columns: ColumnsType<any> = [
  {
    title: '名称',
    dataIndex: 'nickName',
    key: 'nickName',
    ellipsis: true,
  },
  {
    title: '用户名',
    dataIndex: 'userName',
    key: 'userName',
    ellipsis: true,
  },
  {
    title: '手机号码',
    dataIndex: 'phonenumber',
    key: 'phonenumber',
    ellipsis: true,
  },
  {
    title: '部门',
    dataIndex: ['dept', 'deptName'],
    key: 'deptName',
    ellipsis: true,
  },
  {
    title: 'leader',
    dataIndex: ['dept', 'leader'],
    key: 'leader',
    ellipsis: true,
  },
  {
    title: 'leader手机号码',
    dataIndex: ['dept', 'phone'],
    key: 'phone',
    ellipsis: true,
  },
];

//部门列
const deptColumns: ColumnsType<any> = [
  {
    title: '部门名称',
    dataIndex: 'deptName',
    key: 'deptName',
    ellipsis: true,
  },
  {
    title: 'leader',
    dataIndex: 'leader',
    key: 'leader',
  },
  {
    title: 'leader联系方式',
    dataIndex: 'phone',
    key: 'phone',
  },
  {
    title: 'leader邮箱',
    dataIndex: 'email',
    key: 'email',
  },
  {
    title: '状态',
    dataIndex: 'status',
    key: 'status',
  },
  {
    title: '操作',
    key: 'operation',
    fixed: 'right',
    width: 150,
  },
]

const globalStore = useGlobalStore()

const fatherDept = ref<any>([
  {
    label: '主目录',
    value: 0,
    children: []
  }
])

//构造可选的父级部门
const genFatherSelectDept = (data: SysDept[]) => {
  return data.filter((item: SysDept): boolean => {
    item.label = item.deptName
    item.value = item.deptId as number
    if (item.children && item.children?.length !== 0) {
      item.children = genFatherSelectDept(item.children as SysDept[])
    }
    return item.deptType === 'M'
  })
}

const userInDeptData = ref<SysUser[]>([])
const tableLoading = ref(false)

const reloadData = () => {
  getDeptAllTree()
  getDeptUserAll(-1)
}

const dfsDeleteChildrenAndAddKey = (data: SysDept[]) => {
  return data.map((item: SysDept) => {
    item.key = item.deptId
    if (item.children?.length === 0) {
      delete item.children
    } else {
      dfsDeleteChildrenAndAddKey(item.children as SysDept[])
    }
    return item
  })
}

const getDeptAllTree = async () => {
  // 递归处理
  const dfs = (dept: SysDept) => {
    let cur: DataNode = {
      key: dept.deptId as number,
      title: dept.deptName,
      children: [] as DataNode[],
      deptType: dept.deptType,
    }
    if (!dept.children || dept.children.length === 0) {
      delete cur.children
    }
    dept.children?.forEach((nextDept: SysDept) => {
      cur.children?.push(dfs(nextDept) as DataNode)
    })
    return cur
  }
  try {
    isLoading.value = true
    const { data: res }: { data: DeptAllTreeRes } = await deptAllTreeApi()
    deptList.value = dfsDeleteChildrenAndAddKey(res.data)

    deptTreeData.value = []
    res.data.forEach((dept: SysDept) => {
      deptTreeData.value.push(dfs(dept))
    })
    fatherDept.value[0].children = genFatherSelectDept(JSON.parse(JSON.stringify(res.data)))
  } catch (error) {

  } finally {
    isLoading.value = false
  }
}

let deptId = ref(-1)
const selectDept = (selectedKeys: (string | number)[], _info: any) => {
  deptId.value = selectedKeys[0] ? selectedKeys[0] as number : -1
  getDeptUserAll(selectedKeys[0] ? selectedKeys[0] as number : -1)
}

const currentPage = ref(1)
const size = ref(10)
const total = ref(0)

const getDeptUserAll = (deptId: number) => {
  tableLoading.value = true
  getDeptUserAllApi(currentPage.value, size.value, deptId).then(({ data: res }: { data: GetDeptUserAllRes }) => {
    userInDeptData.value = res.data.records
    total.value = res.data.total
  }).finally(() => {
    tableLoading.value = false
  })
}

const pageChanged = (page: number, pageSize: number) => {
  currentPage.value = page
  size.value = pageSize
  getDeptUserAll(deptId.value)
}

//新增部分
const addPopShow = ref(false)
const addApiLoading = ref(false)
const currAddData = ref<SysDept>({
  deptName: '',
  parentId: 0,
  orderNum: 1,
  leader: '',
  phone: '',
  email: '',
  status: '0',
  deptType: 'M'
})
const handleAddData = () => {
  addPopShow.value = true
}

const onFinishFailed = (errorInfo: any) => {
  console.log('Failed:', errorInfo);
};

const handleAddOk = async () => {
  addApiLoading.value = true
  try {
    const { data: res }: { data: CrudBack } = await addDeptApi(currAddData.value)
    if (res.code == 200) {
      message.success('更新成功')
      reloadData()
      addPopShow.value = false
      //清空数据
      currAddData.value = {
        deptName: '',
        parentId: 0,
        orderNum: 1,
        leader: '',
        phone: '',
        email: '',
        status: '0',
      }
    } else {
      message.error(res.msg || '更新失败')
    }
  } catch (error) {

  } finally {
    addApiLoading.value = false
  }
}

//部门数据类
const selectedRows = ref<Key[]>([])
const editPopShow = ref<boolean>(false)
const editApiLoading = ref<boolean>(false)
const currEditData = ref<SysDept>({
  deptId: -1,
  deptName: '',
  parentId: 0,
  orderNum: 1,
  leader: '',
  phone: '',
  email: '',
  status: '0',
  deptType: 'M'
})
const onSelectChange = (selectedRowKeys: Key[]) => {
  selectedRows.value = selectedRowKeys;
  console.log(selectedRows.value);

};

const editData = (sysDept: any) => {
  const { deptId, deptName, parentId, orderNum, leader, phone, email, status, deptType } = sysDept
  currEditData.value.deptId = deptId
  currEditData.value.deptName = deptName
  currEditData.value.parentId = parentId
  currEditData.value.orderNum = orderNum
  currEditData.value.leader = leader
  currEditData.value.phone = phone
  currEditData.value.email = email
  currEditData.value.status = status
  currEditData.value.deptType = deptType
  editPopShow.value = true
}

const handleEditOk = () => {
  editApiLoading.value = true
  updateDeptApi(currEditData.value).then(({ data: res }: { data: R<any> }) => {
    if (res.code === 200) {
      message.success(res.msg || '更新成功')
      reloadData()
      editPopShow.value = false
    }
  }).finally(() => {
    editApiLoading.value = false
  })
}

const deleteData = async (_e: MouseEvent, deptId: number) => {
  deleteDeptApi(deptId.toString()).then(({ data: res }: { data: R<any> }) => {
    if (res.code == 200) {
      message.success('删除成功')
    } else {
      message.error(res.data.msg || '删除失败')
    }
    reloadData()
  })
}

const deleteBatchData = async () => {
  deleteDeptApi(selectedRows.value.join(',')).then(({ data: res }: { data: R<any> }) => {
    if (res.code == 200) {
      message.success('删除成功')
    } else {
      message.error(res.data.msg || '删除失败')
    }
    reloadData()
  })
}

const tableStyle = reactive<{
  width: number,
  height: number
}>({
  width: 300,
  height: 300
})
const contentBoxRef = ref<HTMLElement>()

onMounted(() => {
  getDeptAllTree()
  getDeptUserAll(-1)
  tableStyle.height = contentBoxRef.value?.clientHeight as number - 200
  tableStyle.width = contentBoxRef.value?.clientWidth as number
})
</script>

<template>
  <div class="box-border relative w-full h-full p-6" ref="contentBoxRef"
    :style="{ width: globalStore.isMobile ? 'calc(100% - 60px)' : '100%' }">
    <a-tabs v-model:activeKey="tabKey" type="card">
      <a-tab-pane key="1" tab="部门用户表">
        <div class="flex">
          <div class="min-w-[230px]">
            <a-tree :tree-data="deptTreeData" show-icon @select="selectDept" defaultExpandAll
              v-if="deptTreeData.length > 0" :disabled="tableLoading">
              <template #title="{ title }">
                <span>{{ title }}</span>
              </template>

              <template #icon="{ dataRef }">
                <BankOutlined v-if="dataRef.deptType === 'B'" />
                <ApartmentOutlined v-else />
              </template>
            </a-tree>
          </div>
          <div class="flex-1">
            <a-table :columns="columns" :data-source="userInDeptData" :pagination="false" :loading="tableLoading"
              :scroll="{ y: tableStyle.height, x: globalStore.isMobile ? 'calc(100% + 800px)' : '100%' }">
            </a-table>
          </div>
        </div>
      </a-tab-pane>
      <a-tab-pane key="2" tab="部门表">
        <a-row>
          <a-col :span="24">
            <a-space class="flex mb-4">
              <a-button type="ghost"
                class="flex items-center text-white bg-green-500 hover:bg-green-400 hover:border-green-400 "
                :icon="h(antIcons['PlusOutlined'])" @click="handleAddData" :loading="isLoading">新增</a-button>
              <a-button class="flex items-center justify-center" :icon="h(antIcons['ReloadOutlined'])" shape="circle"
                @click="reloadData"></a-button>
              <a-button type="primary" class="flex items-center" danger :icon="h(antIcons['CloseOutlined'])"
                :disabled="selectedRows.length == 0" @click="deleteBatchData">删除</a-button>
            </a-space>
          </a-col>
        </a-row>

        <a-table :columns="deptColumns" :data-source="deptList" :pagination="false" :loading="isLoading"
          :scroll="{ y: tableStyle.height, x: globalStore.isMobile ? 'calc(100% + 800px)' : '100%' }"
          :row-selection="{ selectedRowKeys: selectedRows, onChange: onSelectChange }">
          <template #bodyCell="{ column, text }">
            <template v-if="column.dataIndex === 'status'">
              <a-switch :checked="text === '0'" disabled>
                <template #checkedChildren>
                  <CheckOutlined />
                </template>
                <template #unCheckedChildren>
                  <CloseOutlined />
                </template>
              </a-switch>
            </template>
            <template v-if="column.key === 'operation'">
              <a-space>
                <a-button type="primary" class="flex items-center bg-primary-2" size="small"
                  @click="editData(text)">编辑</a-button>
                <a-popconfirm :title="`确定删除${text.deptName}吗?`" ok-text="确认" cancel-text="取消"
                  :okButtonProps="{ type: 'default' }" @confirm="deleteData($event, text.deptId)">
                  <a-button size="small" type="primary" danger class="flex items-center text-white ">删除</a-button>
                </a-popconfirm>
              </a-space>
            </template>
          </template>
        </a-table>
      </a-tab-pane>
    </a-tabs>

    <!-- 编辑部分 -->
    <a-modal v-model:open="editPopShow" title="编辑部门" :footer="null" width="700px">
      <a-form :model="currEditData" name="currEditData" @finish="handleEditOk" class="mt-5" place="left" v-bind="{
      labelCol: { span: 8 },
      wrapperCol: { span: 24 },
    }">
        <a-row :gutter="12">
          <a-col :span="12">
            <a-form-item name="deptName" label="部门名称" :rules="[{ required: true }]">
              <a-input v-model:value="currEditData.deptName" placeholder="部门名称" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="parentId" label="所属部门" :rules="[{ required: true }]">
              <a-tree-select v-model:value="currEditData.parentId" show-search style="width: 100%"
                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" placeholder="请选择所属部门" allow-clear
                tree-default-expand-all :tree-data="fatherDept" :defaultValue="currEditData.parentId"
                tree-node-filter-prop="label">
                <template #title="{ label }">
                  <p>{{ label }}</p>
                </template>
              </a-tree-select>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :gutter="12">
          <a-col :span="12">
            <a-form-item name="leader" label="leader" :rules="[{ required: false }]">
              <a-input v-model:value="currEditData.leader" placeholder="leader" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="phone" label="leader联系电话" :rules="[{ required: false }]">
              <a-input v-model:value="currEditData.phone" placeholder="leader联系电话" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="email" label="leader-email" :rules="[{ required: false }]">
              <a-input v-model:value="currEditData.email" placeholder="leader邮箱" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="orderNum" label="排序" :rules="[{ required: false }]">
              <a-input-number v-model:value="currEditData.orderNum" placeholder="排序" />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item name="deptType" label="部门类型" :rules="[{ required: false }]" :labelCol="{
      span: 4
    }">
              <a-radio-group v-model:value="currEditData.deptType" :options="[
      { label: '可分级部门', value: 'M' },
      { label: '无分级部门', value: 'B' },
    ]" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :gutter="12">
          <a-col :span="12">
            <a-form-item name="status" label="部门状态" :rules="[{ required: false }]">
              <a-switch v-model:checked="currEditData.status" checkedValue="0" unCheckedValue="1">
                <template #checkedChildren>
                  <CheckOutlined />
                </template>
                <template #unCheckedChildren>
                  <CloseOutlined />
                </template>
              </a-switch>
            </a-form-item>
          </a-col>
        </a-row>
        <a-form-item :wrapper-col="{
      offset: 19,
      span: 5
    }">
          <a-space>
            <a-button key="back" @click="editPopShow = false">取消</a-button>
            <a-button html-type="submit" type="primary" class="bg-primary-2" :loading="editApiLoading">编辑</a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-modal>

    <a-modal v-model:open="addPopShow" title="新增部门" :footer="null" width="700px">
      <a-form :model="currAddData" name="currAddData" @finish="handleAddOk" class="mt-5" place="left"
        @finishFailed="onFinishFailed" v-bind="{
      labelCol: { span: 8 },
      wrapperCol: { span: 24 },
    }">
        <a-row :gutter="12">
          <a-col :span="12">
            <a-form-item name="deptName" label="部门名称" :rules="[{ required: true }]">
              <a-input v-model:value="currAddData.deptName" placeholder="部门名称" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="parentId" label="所属部门" :rules="[{ required: true }]">
              <a-tree-select v-model:value="currAddData.parentId" show-search style="width: 100%"
                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" placeholder="请选择所属部门" allow-clear
                tree-default-expand-all :tree-data="fatherDept" :defaultValue="currAddData.parentId"
                tree-node-filter-prop="label">
                <template #title="{ label }">
                  <p>{{ label }}</p>
                </template>
              </a-tree-select>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :gutter="12">
          <a-col :span="12">
            <a-form-item name="leader" label="leader" :rules="[{ required: false }]">
              <a-input v-model:value="currAddData.leader" placeholder="leader" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="phone" label="leader联系电话" :rules="[{ required: false }]">
              <a-input v-model:value="currAddData.phone" placeholder="leader联系电话" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="email" label="leader-email" :rules="[{ required: false }]">
              <a-input v-model:value="currAddData.email" placeholder="leader邮箱" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item name="orderNum" label="排序" :rules="[{ required: false }]">
              <a-input-number v-model:value="currAddData.orderNum" placeholder="排序" />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item name="deptType" label="部门类型" :rules="[{ required: false }]" :labelCol="{
      span: 4
    }">
              <a-radio-group v-model:value="currAddData.deptType" :options="[
      { label: '可分级部门', value: 'M' },
      { label: '无分级部门', value: 'B' },
    ]" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row :gutter="12">
          <a-col :span="12">
            <a-form-item name="status" label="部门状态" :rules="[{ required: false }]">
              <a-switch v-model:checked="currAddData.status" checkedValue="0" unCheckedValue="1">
                <template #checkedChildren>
                  <CheckOutlined />
                </template>
                <template #unCheckedChildren>
                  <CloseOutlined />
                </template>
              </a-switch>
            </a-form-item>
          </a-col>
        </a-row>
        <a-form-item :wrapper-col="{
      offset: 19,
      span: 5
    }">
          <a-space>
            <a-button key="back" @click="addPopShow = false">取消</a-button>
            <a-button html-type="submit" type="primary" class="bg-primary-2" :loading="addApiLoading">新增</a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-modal>

    <div
      class="absolute bottom-0 left-0 right-0 p-3 mt-3 bg-white border-t-[1px] z-10 dark:bg-darkBg dark:border-gray-600"
      v-if="tabKey === '1'">
      <a-pagination v-model:current="currentPage" v-model:page-size="size" :total="total"
        :show-total="total => `总共 ${total} 条`" show-size-changer @change="pageChanged" />
    </div>
  </div>
</template>

<style scoped></style>